package com.leinao.nio;

import com.leinao.file.dto.FileProcessDataDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 *
 * @Description ZIP压缩处理
 * @author lizi
 * @date 2018/11/20 上午9:10
 * @Version 1.0
 */
public class ZipTree extends SimpleFileVisitor<Path> {
    private static Logger logger = LoggerFactory.getLogger(ZipTree.class);

    private Path sourceDir;
    private ZipOutputStream zipOutputStream;
    private FileProcessDataDto fileProcessData;

    public ZipTree(Path sourceDir, ZipOutputStream zipOutputStream, FileProcessDataDto fileProcessData) {
        this.sourceDir = sourceDir;
        this.zipOutputStream = zipOutputStream;
        this.fileProcessData = fileProcessData;
    }

    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
        logger.info("Zip directory: {}", dir);
        //处理文件夹
        Path downloadPath = sourceDir.relativize(dir);
        zipOutputStream.putNextEntry(new ZipEntry(downloadPath.toString() + "/"));
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) throws IOException {
        // 软链接特殊处理
        if(Files.isSymbolicLink(file)) {
            //软链接目录处理
            if(Files.isDirectory(file)) {
                Path downloadPath = sourceDir.relativize(file);
                zipOutputStream.putNextEntry(new ZipEntry(downloadPath.toString() + "/"));
            }
            // 软链接默认处理
            return FileVisitResult.CONTINUE;
        }

        logger.info("Zip file: {}", file);
        Path downloadPath = sourceDir.relativize(file);
        zipOutputStream.putNextEntry(new ZipEntry(downloadPath.toString()));
        InputStream fis = Files.newInputStream(file);
        ReadableByteChannel srcChannel = Channels.newChannel(fis);
        WritableByteChannel destChannel = Channels.newChannel(zipOutputStream);

        int buffer = 4096;
        long totalSize = 0;
        ByteBuffer data = ByteBuffer.allocate(buffer);
        int read = srcChannel.read(data);
        while(read > 0) {
            totalSize += read;
            data.flip();
            destChannel.write(data);
            data.clear();
            read = srcChannel.read(data);
        }

        // 下载的文件大小统计
        fileProcessData.setBandWidth(fileProcessData.getBandWidth().add(BigDecimal.valueOf(totalSize)));

        srcChannel.close();
        return FileVisitResult.CONTINUE;
    }
}
